#include <stdio.h>

/*
 * this will demostrate how does the variable argument works
 */
typedef char * va_list;

#define __va_size(type)                                                 \
    (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))

#define va_start(ap, last)                      \
    ((ap) = (va_list)&(last) + __va_size(last))

#define va_arg(ap, type)                                            \
    (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))

#define va_end(ap)  ((void)0)

int std_add (int count, ...)
{
    char *p;
    int i, sum = 0, arg;

    va_start(p, count);

    for (i=0; i < count; ++i) {
        arg = va_arg(p, int);
        sum += arg;
    }

    va_end();

    return sum;
}


int my_add (int count, ...)
{
    int i, sum = 0, arg, *p;

    if (count < 1) {
        return 0;
    }

    p = &count;

    for (i=0; i < count; ++i) {
        arg = *(p+i+1);
        sum += arg;
    }

    return sum;
}


int main(int argc, char *argv[])
{
    extern int std_add (int count, ...);
    extern int my_add (int count, ...);

    printf("std_add(3,6,4,5) = %d\n", std_add(3, 6, 4, 5));
    printf("std_add(3,6,4,5,2) = %d\n", std_add(3, 6, 4, 5, 2));

    printf("my_add(3,6,4,5) = %d\n", my_add(3, 6, 4, 5));
    printf("my_add(3,6,4,5,2) = %d\n", my_add(3, 6, 4, 5, 2));

    return 0;
}

